/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Server.BUS;

import Server.DTO.Database;
import Server.DTO.EditTableDTO;
import Server.DTO.Query;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.table.DefaultTableModel;
import javax.xml.parsers.ParserConfigurationException;

/**
 *
 * @author QuangKhai
 */
public class Transporter implements Runnable{
    private ObjectOutputStream oos;        
    private ObjectInputStream ois;
    private Socket socket;
    private String username;
    private String password;
    private Query query;// = new Query();
    //private EditTableDTO editTableDTO = new EditTableDTO();
    //private QueryBUS queryBUS = new QueryBUS();
    private List<Database> lstDB = new ArrayList<Database>();
        
    public Transporter(Socket socket, List<Database> _lstDB) throws IOException{        
        this.socket = socket;  
        this.lstDB = _lstDB;
    }
    
    public void setConnection() throws IOException{
        this.oos = new ObjectOutputStream(socket.getOutputStream()); 
        this.ois = new ObjectInputStream(socket.getInputStream());
        
        sendDBList();
        oos.flush();        
    }
    
    public List<String> recieveClient() throws IOException{
        List<String> client = new ArrayList<String>();
        
        client.add(ois.readUTF());
        client.add(ois.readUTF());
        
        return client;
    }
    
    public void sendState(boolean state) throws IOException{
        if(state){
            oos.writeUTF("Kết nối thành công");
            oos.flush();            
        }else{
            oos.writeUTF("Đăng nhập không hợp lệ");
            oos.flush();            
        }
    }
    
    public int recieveType() throws IOException{ 
        String s = ois.readUTF();
        if(s.compareTo("Client") == 0){
            return 1;
        } else if(s.compareTo("Execute") == 0){
            return 2;
        }               
        return 0;
    }
    
    public void sendResult() throws IOException, ParserConfigurationException{
//        String type = query.getQuerySentences().get(0).split(" ")[0];
//        DatabaseDTO databaseDTO = new DatabaseDTO();
//        
//        for(int i = 0; i < lstDB.size(); i++){
//            if(lstDB.get(i).getDatabaseName().compareTo(query.getDatabaseName()) == 0){
//                databaseDTO = lstDB.get(i);
//                break;
//            }
//        }
//        
//        if(type.compareTo("SELECT") == 0){
//            editTableDTO = queryBUS.getSelectResults(query.getQuerySentences().get(0), databaseDTO);
//            sendEditTable(editTableDTO);
//        }else if(type.compareTo("INSERT") == 0){
//            editTableDTO = queryBUS.getInsertResults(query.getQuerySentences().get(0), databaseDTO);
//            sendEditTable(editTableDTO);
//        } else if(type.compareTo("DELETE") == 0){
//            editTableDTO = queryBUS.getDeleteResults(query.getQuerySentences().get(0), databaseDTO);
//            sendEditTable(editTableDTO);
//        } else if(type.compareTo("UPDATE") == 0){
//            editTableDTO = queryBUS.getUpdateResults(query.getQuerySentences().get(0), databaseDTO);
//            sendEditTable(editTableDTO);
//            
//        }    
    }  
    
    public void sendEditTable(EditTableDTO editTable) throws IOException{
        int colums = editTable.getColumnName().size();
        oos.writeInt(colums);
        oos.reset();
        
        for(int i = 0; i < colums; i++){
            oos.writeUTF(editTable.getColumnName().get(i));
            oos.reset();
        }
        
        int values = editTable.getLstValues().size();
        oos.writeInt(values);
        oos.reset();
        for(int i = 0; i < values; i++){
            for(int j = 0; j < colums; j++){
                oos.writeUTF(editTable.getLstValues().get(i).get(j));
                oos.reset();
            }
        }
    }
    
    public void sendDBList() throws IOException
    {
        oos.writeInt(lstDB.size());
        int nDB = lstDB.size();
        for(int i = 0; i < nDB; i++)
        {
            oos.writeUTF(lstDB.get(i).getName());//Danh sach ten cac DB
            oos.reset();              
        }
    }
    
    public void sendTableModel(DefaultTableModel model) throws IOException
    {
        oos.writeObject(model);
    }
    
    public void sendDBList1() throws IOException{
        int nDB = lstDB.size();
        oos.writeInt(nDB);//So luong DB
        oos.reset();
        
        for(int i = 0; i < nDB; i++)
        {            
            oos.writeUTF(lstDB.get(i).getName());//Danh sach ten cac DB
            oos.reset();       
            
            oos.writeInt(lstDB.get(i).getTables().size());//So luong Tables
            oos.reset();       
            int nTable = lstDB.get(i).getTables().size();
            for(int j = 0; j < nTable; j++)
            {
                oos.writeUTF(lstDB.get(i).getTables().get(j).getName());//Danh sach ten cac tables
                oos.reset();  
                
                oos.writeInt(lstDB.get(i).getTables().get(j).getColumns().size());//So luong cac Columns
                oos.reset();       
                int nCol = lstDB.get(i).getTables().get(j).getColumns().size();
                for(int k = 0; k < nCol; k++)
                {
                    oos.writeUTF(lstDB.get(i).getTables().get(j).getColumns().get(k).getName());//Danh sach ten cac columns
                    oos.reset();  
                    
                    oos.writeInt(lstDB.get(i).getTables().get(j).getColumns().get(k).getRowsList().size());//So luong cac cot
                    oos.reset();
                    
                    int nRow = lstDB.get(i).getTables().get(j).getColumns().get(k).getRowsList().size();
                    for(int row = 0; row < nRow; i++)
                    {
                        oos.writeUTF(lstDB.get(i).getTables().get(j).getColumns().get(k).getRowsList().get(row).getText());
                        oos.reset();
                    }
                }
                
            }
        }
    }
    
    public String receiveQuery() throws IOException, ClassNotFoundException{        

        return ois.readUTF();
    }
    
    public void processClient() throws IOException{
        List<String> client = recieveClient();
        
        if(client.get(0).compareTo(username) == 0 && client.get(1).compareTo(password) == 0){
            sendState(true);
            sendDBList1();
        }else{
            sendState(false);
        }
    }
    
    public void processQuery() throws IOException, ClassNotFoundException, ParserConfigurationException{
//        query = receiveQuery();
//        sendResult();
    }
    
    @Override
    public void run() {  
        try {
            setConnection();
        } catch (IOException ex) {
            Logger.getLogger(Transporter.class.getName()).log(Level.SEVERE, null, ex);
        }
        while(true){
            try
            {
                String queryString = StringUlti.formatString(receiveQuery());
            }
            catch(IOException ex)
            {
                ex.printStackTrace();
            }
            catch(ClassNotFoundException cex)
            {
                cex.printStackTrace();
            }
            

        }
    }
}
